package com.cy.utils;

import com.jfinal.plugin.ehcache.CacheKit;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

/**
 * 扩展JFinal的CacheKit，支持加锁数据
 */
public class ConcurrentCacheKit {

    public static Cache getOrAddCache(String cacheName) {
        CacheManager cacheManager = CacheKit.getCacheManager();
        Cache cache = cacheManager.getCache(cacheName);
        if (cache == null) {
            synchronized(cacheManager) {
                cache = cacheManager.getCache(cacheName);
                if (cache == null) {
                    cacheManager.addCacheIfAbsent(cacheName);
                    cache = cacheManager.getCache(cacheName);
                }
            }
        }
        return cache;
    }

    /**
     * 带锁的写入数据
     */
    public static void put(String cacheName, Object key, Object value) {
        boolean isLocked = false;
        Cache cache = getOrAddCache(cacheName);
        try {
            isLocked = cache.tryWriteLockOnKey(key, 3000);//尝试获取写锁3秒超时
            cache.put(new Element(key, value));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁
            if (isLocked)
                cache.releaseWriteLockOnKey(key);
        }
    }

    /**
     * 带锁的写入数据(不覆盖相同key)
     */
    public static void putIfAbsent(String cacheName, Object key, Object value) {
        boolean isLocked = false;
        Cache cache = getOrAddCache(cacheName);
        try {
            isLocked = cache.tryWriteLockOnKey(key, 3000);//尝试获取写锁3秒超时
            cache.putIfAbsent(new Element(key, value));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁
            if (isLocked)
                cache.releaseWriteLockOnKey(key);
        }
    }

}
